%     FASTENER DOCTOR - программа для лечения и конвертации крепежа
%     Copyright (C) 2018  Михаил Козлов
%     Сайт проекта: <http://www.fastenerdoctor.ru/>
%     Адрес электронной почты для связи с разработчиком:
%     <doctor.fastener@gmail.com>
% 
%     Эта программа является свободным программным обеспечением: Вы можете
%     распространять ее и/или изменять, соблюдая условия Универсальной общественной
%     лицензии GNU, опубликованной Фондом свободного программного обеспечения,
%     либо редакции 3, либо (на Ваше усмотрение) любой редакции, выпущенной позже.
% 
%     Эта программа распространяется в надежде на то, что она окажется полезной,
%     но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая даже подразумеваемую гарантию ТОВАРНОЙ ПРИГОДНОСТИ,
%     либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Универсальной общественной
%     лицензией GNU для получения более подробной информации.
% 
%     Вы должны были получить копию Универсальной общественной лицензии GNU
%     вместе с этой программой. Если Вы ее не получили, то перейдите по адресу:
%     <http://www.gnu.org/licenses/>.
% 
%     This program is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
% 
%     This program is distributed in the hope that it will be useful,
%     but WITHOUT ANY WARRANTY; without even the implied warranty of
%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%     GNU General Public License for more details.
% 
%     You should have received a copy of the GNU General Public License
%     along with this program.  If not, see <https://www.gnu.org/licenses/>.

function DB_MATERIALS = Create_DB_MATERIALS(MATERIALS)

% До обработки:

% MATERIALS (карточка MAT1) | .card | .ID | .Patran_name | .E | .G | .NU | .RHO | .A | .TREF | .GE | .ST | .SC | .SS | .MCSID |
% MATERIALS (карточка MAT2) | .card | .ID | .Patran_name | .G11 | .G12 | .G13 |
%                                                               | .G22 | .G23 |
%                                                                      | .G33 |
%                                                                      | .RHO | .A1 | .A2 | .A3 | .TREF | .GE | .ST | .SC | .SS | .MCSID | .GE11 | .GE12 | .GE13 | .GE22 | .GE23 | .GE33 |
% MATERIALS (карточка MAT8) | .card | .ID | .Patran_name | .E1 | .E2 | .NU12 | .G12 | .G1Z | .G2Z | .RHO | .A1 | .A2 | .TREF | .Xt | .Xc | .Yt | .Yc | .S | .GE | .F12 | .STRN |
% MATERIALS (карточка MAT9) | .card | .ID | .Patran_name | .G11 | .G12 | .G13 | .G14 | .G15 | .G16 |
%                                                               | .G22 | .G23 | .G24 | .G25 | .G26 |
%                                                                      | .G33 | .G34 | .G35 | .G36 |
%                                                                             | .G44 | .G45 | .G46 |
%                                                                                    | .G55 | .G56 |
%                                                                                           | .G66 |
%                                                                                           | .RHO | .A1 | .A2 | .A3 | .A4 | .A5 | .A6 | .TREF | .GE | .GE11 | .GE12 | .GE13 | .GE14 | .GE15 | .GE16 | .GE22 | .GE23 | .GE24 | .GE25 | .GE26 | .GE33 | .GE34 | .GE35 | .GE36 | .GE44 | .GE45 | .GE46 | .GE55 | .GE56 | .GE66 |
%                                                                                           Расшифровка номеров сдвиговых компонент: 4 - 12, 5 - 23, 6 - 31
%
%    nu12*E2 = nu21*E1
%    nu23*E3 = nu32*E2
%    nu13*E3 = nu31*E1


% После обработки:

% DB_MATERIALS (isotropic)      | .type | .ID | .Patran_name | .E | .nu |
% DB_MATERIALS (2d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .nu12 | .G12 |
% DB_MATERIALS (2d_anisotropic) | .type | .ID | .Patran_name | .C(3,3) - матрица Гука |                                         ### Сдвиговые деформации инженерные
% DB_MATERIALS (3d_orthotropic) | .type | .ID | .Patran_name | .E1 | .E2 | .E3 | .G12 | .G23 | .G13 | .nu12 | .nu23 | .nu13 |   ### nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (3d_anisotropic) | .type | .ID | .Patran_name | .C(6,6) - матрица Гука |                                         ### Сдвиговые деформации инженерные # Расшифровка номеров сдвиговых компонент: 4 - 12, 5 - 23, 6 - 13 # nu12*E2 = nu21*E1 # nu23*E3 = nu32*E2 # nu13*E3 = nu31*E1
% DB_MATERIALS (pshell_MAT2_for_transverse_shear) | .type | .ID | .Patran_name | .C(2,2) - матрица Гука |

global ErrCode;

global MAT2_orthotropic_tolerance_multiplier;
global MAT9_orthotropic_tolerance_multiplier;

fprintf (1, 'Обработка материалов...                 ');

DB_MATERIALS = cell(size(MATERIALS,1),1);

for i=1:size(MATERIALS,1)

    switch MATERIALS{i}.card
        
        case 'MAT1'
            
            DB_MATERIALS{i}.type = 'isotropic';
            DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
            DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
            
            % Если одновременно заданы все три константы
            if ((~isempty(MATERIALS{i}.E)) && (~isempty(MATERIALS{i}.G)) && (~isempty(MATERIALS{i}.NU)))
                E = MATERIALS{i}.E;
                nu = MATERIALS{i}.NU;
            end
            
            % Если не задано E
            if (isempty(MATERIALS{i}.E))
                E = 2*(1+MATERIALS{i}.NU)*MATERIALS{i}.G;
                nu = MATERIALS{i}.NU;
            end
            
            % Если не задано G
            if (isempty(MATERIALS{i}.G))
                E = MATERIALS{i}.E;
                nu = MATERIALS{i}.NU;
            end
            
            % Если не задано nu
            if (isempty(MATERIALS{i}.NU))
                E = MATERIALS{i}.E;
                nu = MATERIALS{i}.E / 2 / MATERIALS{i}.G - 1;
            end
            
            DB_MATERIALS{i}.E = E;
            DB_MATERIALS{i}.nu = nu;
            
        case 'MAT2'
            
            trace_array = zeros(3,1);
            trace_array(1) = abs(MATERIALS{i}.G11);
            trace_array(2) = abs(MATERIALS{i}.G22);
            trace_array(3) = abs(MATERIALS{i}.G33);
            
            % Случай материала MAT2 без G13, G23, G33 для поля MID3 карточки PSHELL
            if ((MATERIALS{i}.G33 == 0) && (MATERIALS{i}.G23 == 0) && (MATERIALS{i}.G13 == 0))
                
                DB_MATERIALS{i}.type = 'pshell_MAT2_for_transverse_shear';
                DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
                DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
                DB_MATERIALS{i}.C = zeros(2,2);
                
                DB_MATERIALS{i}.C(1,1) = MATERIALS{i}.G11;
                DB_MATERIALS{i}.C(1,2) = MATERIALS{i}.G12;
                DB_MATERIALS{i}.C(2,1) = DB_MATERIALS{i}.C(1,2);
                DB_MATERIALS{i}.C(2,2) = MATERIALS{i}.G22;
                
                continue;
                
            end
            
            % Нормальный случай
            if (abs(MATERIALS{i}.G13) + abs(MATERIALS{i}.G23) < max(trace_array)*MAT2_orthotropic_tolerance_multiplier)
                
                C = zeros(3,3);
                
                C(1,1) = MATERIALS{i}.G11;
                C(1,2) = MATERIALS{i}.G12;
                C(2,1) = C(1,2);
                C(2,2) = MATERIALS{i}.G22;
                C(3,3) = MATERIALS{i}.G33;
                
                D = inv(C);
                
                E1 = 1/D(1,1);
                E2 = 1/D(2,2);
                G12 = 1/D(3,3);
                nu12 = -D(1,2)/D(1,1);
                
                DB_MATERIALS{i}.type = '2d_orthotropic';
                DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
                DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
                
                DB_MATERIALS{i}.E1 = E1;
                DB_MATERIALS{i}.E2 = E2;
                DB_MATERIALS{i}.nu12 = nu12;
                DB_MATERIALS{i}.G12 = G12;
                
            else
                
                DB_MATERIALS{i}.type = '2d_anisotropic';
                DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
                DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
                DB_MATERIALS{i}.C = zeros(3,3);
                
                DB_MATERIALS{i}.C(1,1) = MATERIALS{i}.G11;
                DB_MATERIALS{i}.C(1,2) = MATERIALS{i}.G12;
                DB_MATERIALS{i}.C(1,3) = MATERIALS{i}.G13;
                
                DB_MATERIALS{i}.C(2,1) = DB_MATERIALS{i}.C(1,2);
                DB_MATERIALS{i}.C(2,2) = MATERIALS{i}.G22;
                DB_MATERIALS{i}.C(2,3) = MATERIALS{i}.G23;
                
                DB_MATERIALS{i}.C(3,1) = DB_MATERIALS{i}.C(1,3);
                DB_MATERIALS{i}.C(3,2) = DB_MATERIALS{i}.C(2,3);
                DB_MATERIALS{i}.C(3,3) = MATERIALS{i}.G33;
                
            end
            
        case 'MAT8'
            
            DB_MATERIALS{i}.type = '2d_orthotropic';
            DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
            DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
            DB_MATERIALS{i}.E1 = MATERIALS{i}.E1;
            DB_MATERIALS{i}.E2 = MATERIALS{i}.E2;
            DB_MATERIALS{i}.nu12 = MATERIALS{i}.NU12;
            DB_MATERIALS{i}.G12 = MATERIALS{i}.G12;
            
        case 'MAT9'
            
            trace_array = zeros(6,1);
            trace_array(1) = abs(MATERIALS{i}.G11);
            trace_array(2) = abs(MATERIALS{i}.G22);
            trace_array(3) = abs(MATERIALS{i}.G33);
            trace_array(4) = abs(MATERIALS{i}.G44);
            trace_array(5) = abs(MATERIALS{i}.G55);
            trace_array(6) = abs(MATERIALS{i}.G66);
            
            if (abs(MATERIALS{i}.G14) + abs(MATERIALS{i}.G15) + abs(MATERIALS{i}.G16) + ...
                abs(MATERIALS{i}.G24) + abs(MATERIALS{i}.G25) + abs(MATERIALS{i}.G26) + ...
                abs(MATERIALS{i}.G34) + abs(MATERIALS{i}.G35) + abs(MATERIALS{i}.G36) + ...
                                              abs(MATERIALS{i}.G45) + abs(MATERIALS{i}.G46) + ...
                                                                            abs(MATERIALS{i}.G56) < max(trace_array)*MAT9_orthotropic_tolerance_multiplier)
                
                C = zeros(6,6);
                
                C(1,1) = MATERIALS{i}.G11;
                C(1,2) = MATERIALS{i}.G12;
                C(1,3) = MATERIALS{i}.G13;
                
                C(2,1) = C(1,2);
                C(2,2) = MATERIALS{i}.G22;
                C(2,3) = MATERIALS{i}.G23;
                
                C(3,1) = C(1,3);
                C(3,2) = C(2,3);
                C(3,3) = MATERIALS{i}.G33;
                
                C(4,4) = MATERIALS{i}.G44;
                C(5,5) = MATERIALS{i}.G55;
                C(6,6) = MATERIALS{i}.G66;
                
                D = inv(C);
                
                E1 = 1/D(1,1);
                E2 = 1/D(2,2);
                E3 = 1/D(3,3);
                
                G12 = 1/D(4,4);
                G23 = 1/D(5,5);
                G13 = 1/D(6,6);
                
                nu12 = -D(1,2)/D(1,1);
                nu23 = -D(2,3)/D(2,2);
                nu13 = -D(1,3)/D(1,1);
                
                DB_MATERIALS{i}.type = '3d_orthotropic';
                DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
                DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
                
                DB_MATERIALS{i}.E1 = E1;
                DB_MATERIALS{i}.E2 = E2;
                DB_MATERIALS{i}.E3 = E3;
                
                DB_MATERIALS{i}.G12 = G12;
                DB_MATERIALS{i}.G23 = G23;
                DB_MATERIALS{i}.G13 = G13;
                
                DB_MATERIALS{i}.nu12 = nu12;
                DB_MATERIALS{i}.nu23 = nu23;
                DB_MATERIALS{i}.nu13 = nu13;
                
            else
                
                DB_MATERIALS{i}.type = '3d_anisotropic';
                DB_MATERIALS{i}.ID = MATERIALS{i}.ID;
                DB_MATERIALS{i}.Patran_name = MATERIALS{i}.Patran_name;
                DB_MATERIALS{i}.C = zeros(6,6);
                
                DB_MATERIALS{i}.C(1,1) = MATERIALS{i}.G11;
                DB_MATERIALS{i}.C(1,2) = MATERIALS{i}.G12;
                DB_MATERIALS{i}.C(1,3) = MATERIALS{i}.G13;
                DB_MATERIALS{i}.C(1,4) = MATERIALS{i}.G14;
                DB_MATERIALS{i}.C(1,5) = MATERIALS{i}.G15;
                DB_MATERIALS{i}.C(1,6) = MATERIALS{i}.G16;
                
                DB_MATERIALS{i}.C(2,1) = DB_MATERIALS{i}.C(1,2);
                DB_MATERIALS{i}.C(2,2) = MATERIALS{i}.G22;
                DB_MATERIALS{i}.C(2,3) = MATERIALS{i}.G23;
                DB_MATERIALS{i}.C(2,4) = MATERIALS{i}.G24;
                DB_MATERIALS{i}.C(2,5) = MATERIALS{i}.G25;
                DB_MATERIALS{i}.C(2,6) = MATERIALS{i}.G26;
                
                DB_MATERIALS{i}.C(3,1) = DB_MATERIALS{i}.C(1,3);
                DB_MATERIALS{i}.C(3,2) = DB_MATERIALS{i}.C(2,3);
                DB_MATERIALS{i}.C(3,3) = MATERIALS{i}.G33;
                DB_MATERIALS{i}.C(3,4) = MATERIALS{i}.G34;
                DB_MATERIALS{i}.C(3,5) = MATERIALS{i}.G35;
                DB_MATERIALS{i}.C(3,6) = MATERIALS{i}.G36;
                
                DB_MATERIALS{i}.C(4,1) = DB_MATERIALS{i}.C(1,4);
                DB_MATERIALS{i}.C(4,2) = DB_MATERIALS{i}.C(2,4);
                DB_MATERIALS{i}.C(4,3) = DB_MATERIALS{i}.C(3,4);
                DB_MATERIALS{i}.C(4,4) = MATERIALS{i}.G44;
                DB_MATERIALS{i}.C(4,5) = MATERIALS{i}.G45;
                DB_MATERIALS{i}.C(4,6) = MATERIALS{i}.G46;
                
                DB_MATERIALS{i}.C(5,1) = DB_MATERIALS{i}.C(1,5);
                DB_MATERIALS{i}.C(5,2) = DB_MATERIALS{i}.C(2,5);
                DB_MATERIALS{i}.C(5,3) = DB_MATERIALS{i}.C(3,5);
                DB_MATERIALS{i}.C(5,4) = DB_MATERIALS{i}.C(4,5);
                DB_MATERIALS{i}.C(5,5) = MATERIALS{i}.G55;
                DB_MATERIALS{i}.C(5,6) = MATERIALS{i}.G56;
                
                DB_MATERIALS{i}.C(6,1) = DB_MATERIALS{i}.C(1,6);
                DB_MATERIALS{i}.C(6,2) = DB_MATERIALS{i}.C(2,6);
                DB_MATERIALS{i}.C(6,3) = DB_MATERIALS{i}.C(3,6);
                DB_MATERIALS{i}.C(6,4) = DB_MATERIALS{i}.C(4,6);
                DB_MATERIALS{i}.C(6,5) = DB_MATERIALS{i}.C(5,6);
                DB_MATERIALS{i}.C(6,6) = MATERIALS{i}.G66;
                
            end
            
        otherwise
            
            fprintf (1, '\nНеизвестная карточка материала %i [%s] !\n', MATERIALS{i}.ID, MATERIALS{i}.card);
            ErrCode = -1;
            return;
        
    end
    
end

fprintf (1, 'OK!\n');
